﻿using NPOI.HSSF.UserModel;
using NPOI.SS.Converter;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Yz.Core.Tools.Excel;

namespace Yz.Core.Tools
{
    public class YzExcel
    {
        public static string ToHtml(string filePath)
        { 
            StringBuilder stringBuilder = new StringBuilder();
            FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            ISheet val = null;
            int num = 0;
            List<ExcelSheetModel> list = new List<ExcelSheetModel>();
            try
            {
                if (filePath.IndexOf(".xlsx") == -1)
                {
                    HSSFWorkbook val2 = new HSSFWorkbook((Stream)fileStream);
                    num = val2.NumberOfSheets;
                    for (int i = 0; i < num; i++)
                    {
                        val = val2.GetSheetAt(i);
                        ExcelSheetModel excelSheetModel = new ExcelSheetModel
                        {
                            Id = "sheet" + i.ToString(),
                            Name = val.SheetName
                        };
                        FormatSheet(val, excelSheetModel);
                        list.Add(excelSheetModel);
                    }
                }
                else
                {
                    XSSFWorkbook val3 = new XSSFWorkbook((Stream)fileStream);
                    num = val3.NumberOfSheets;
                    for (int j = 0; j < num; j++)
                    {
                        val = val3.GetSheetAt(j);
                        ExcelSheetModel excelSheetModel2 = new ExcelSheetModel
                        {
                            Id = "sheet" + j.ToString(),
                            Name = val.SheetName
                        };
                        FormatSheet(val, excelSheetModel2);
                        list.Add(excelSheetModel2);
                    }
                }
                stringBuilder.Append(HtmlHelper.GetExcelHtml(list));
                return stringBuilder.ToString();
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                fileStream.Close();
                fileStream.Dispose();
            }
        }

        private static void FormatSheet(ISheet sheet, ExcelSheetModel sheetModel)
        { 
            Dictionary<string, ExcelMergeCellModel> dictionary = new Dictionary<string, ExcelMergeCellModel>();
            decimal num = default(decimal);
            int num2 = 0;
            List<ExcelRowModel> list = new List<ExcelRowModel>();
            for (int i = 0; i < sheet.NumMergedRegions; i++)
            {
                CellRangeAddress mergedRegion = sheet.GetMergedRegion(i);
                ExcelMergeCellModel value = new ExcelMergeCellModel
                {
                    RowSpan = mergedRegion.LastRow - mergedRegion.FirstRow + 1,
                    ColumnSpan = mergedRegion.LastColumn - mergedRegion.FirstColumn + 1,
                    FirstRowIndex = mergedRegion.FirstRow,
                    LastRowIndex = mergedRegion.LastRow,
                    FirstColumnIndex = mergedRegion.FirstColumn,
                    LastColumnIndex = mergedRegion.LastColumn
                };
                string key = mergedRegion.FirstRow.ToString() + "." + mergedRegion.FirstColumn.ToString();
                dictionary.Add(key, value);
            }
            for (int j = 0; j <= sheet.LastRowNum; j++)
            {
                ExcelRowModel excelRowModel = new ExcelRowModel();
                List<ExcelCellModel> list2 = new List<ExcelCellModel>();
                IRow row = sheet.GetRow(j);
                if (row != null)
                {
                    for (int k = 0; k < row.LastCellNum; k++)
                    {
                        ExcelCellModel excelCellModel = new ExcelCellModel();
                        ICell cell = row.GetCell(k);
                        if (cell != null)
                        {
                            IWorkbook workbook = sheet.Workbook;
                            excelCellModel.Alignment = cell.CellStyle.Alignment;
                            excelCellModel.VerticalAlignment = cell.CellStyle.VerticalAlignment;
                            excelCellModel.BorderTop = cell.CellStyle.BorderTop;
                            excelCellModel.BorderRight = cell.CellStyle.BorderRight;
                            excelCellModel.BorderBottom = cell.CellStyle.BorderBottom;
                            excelCellModel.BorderLeft = cell.CellStyle.BorderLeft;
                            if (cell.CellStyle is XSSFCellStyle)
                            {
                                XSSFCellStyle val = (XSSFCellStyle)cell.CellStyle;
                                if (val.TopBorderXSSFColor == null || !val.TopBorderXSSFColor.IsAuto)
                                {
                                    excelCellModel.BorderTopColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.TopBorderColor);
                                }
                                if (val.RightBorderXSSFColor == null || !val.RightBorderXSSFColor.IsAuto)
                                {
                                    excelCellModel.BorderRightColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.RightBorderColor);
                                }
                                if (val.BottomBorderXSSFColor == null || !val.BottomBorderXSSFColor.IsAuto)
                                {
                                    excelCellModel.BorderBottomColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.BottomBorderColor);
                                }
                                if (val.LeftBorderXSSFColor == null || !val.LeftBorderXSSFColor.IsAuto)
                                {
                                    excelCellModel.BorderLeftColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.LeftBorderColor);
                                }
                            }
                            else
                            {
                                excelCellModel.BorderTopColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.TopBorderColor);
                                excelCellModel.BorderRightColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.RightBorderColor);
                                excelCellModel.BorderBottomColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.BottomBorderColor);
                                excelCellModel.BorderLeftColor = ExcelToHtmlUtils.GetHexColor(workbook, cell.CellStyle.LeftBorderColor);
                            }
                            excelCellModel.WrapText = cell.CellStyle.WrapText;
                            if ((double)row.HeightInPoints != 13.5)
                            {
                                excelCellModel.HeightInPoints = row.HeightInPoints;
                            }
                            else
                            {
                                excelCellModel.HeightInPoints = 0f;
                            }
                            excelCellModel.FillColor = ExcelToHtmlUtils.GetHexBgColor(workbook, cell.CellStyle);
                            if (workbook != null)
                            {
                                excelCellModel.Font = cell.CellStyle.GetFont(sheet.Workbook);
                                excelCellModel.FontColor = ExcelToHtmlUtils.GetHexFontColor(workbook, excelCellModel.Font);
                            }
                            excelCellModel.Text = GetCellText(cell, cell.CellType, excelCellModel);
                            if ((int)cell.CellStyle.BorderDiagonal > 0)
                            {
                                excelCellModel.Text = FormatText(excelCellModel.Text);
                            }
                            if (cell.IsMergedCell)
                            {
                                string key2 = j.ToString() + "." + k.ToString();
                                if (dictionary.ContainsKey(key2))
                                {
                                    ExcelMergeCellModel excelMergeCellModel = dictionary[key2];
                                    excelCellModel.ColumnSpan = excelMergeCellModel.ColumnSpan;
                                    excelCellModel.RowSpan = excelMergeCellModel.RowSpan;
                                    list2.Add(excelCellModel);
                                }
                            }
                            else
                            {
                                excelCellModel.ColumnSpan = 1;
                                excelCellModel.RowSpan = 1;
                                list2.Add(excelCellModel);
                            }
                        }
                        else
                        {
                            excelCellModel.Text = "";
                            excelCellModel.ColumnSpan = 1;
                            excelCellModel.RowSpan = 1;
                            list2.Add(excelCellModel);
                        }
                        if (k > num2)
                        {
                            num2 = k;
                        }
                    }
                }
                else
                {
                    ExcelCellModel excelCellModel2 = new ExcelCellModel();
                    excelCellModel2.Text = "";
                    excelCellModel2.ColumnSpan = 1;
                    excelCellModel2.RowSpan = 1;
                    list2.Add(excelCellModel2);
                }
                excelRowModel.Cells = list2;
                list.Add(excelRowModel);
            }
            List<decimal> list3 = new List<decimal>();
            for (int l = 0; l <= num2; l++)
            {
                decimal num3 = widthToPixels(sheet.GetColumnWidth(l));
                if (num3 == decimal.Zero)
                {
                    num3 = 72m;
                }
                num += num3;
                list3.Add(num3);
            }
            sheetModel.Rows = list;
            sheetModel.TableWidth = num;
            sheetModel.CellWidths = list3;
        }

        private static int widthToPixels(double widthUnits)
        {
            return (int)Math.Round(widthUnits * 9.0 / 256.0);
        }
        private static string FormatText(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return "";
            }
            string text2 = text.Trim();
            string str = text.Replace(text2, "");
            return str + text2.Replace(" ", "  ");
        }

        private static string GetCellText(ICell cell, CellType cellType, ExcelCellModel cellm)
        { 
            cellm.CellType = cellType;
            string result = "";
            switch (cellType)
            {
                case CellType.Numeric:
                    result = cell.StringCellValue;
                    break;
                case CellType.String:
                    {
                        string dataFormatString = cell.CellStyle.GetDataFormatString();
                        result = ((dataFormatString == "General") ? cell.NumericCellValue.ToString() : ((!DateUtil.IsCellDateFormatted(cell)) ? cell.NumericCellValue.ToString(dataFormatString) : cell.DateCellValue.ToString(dataFormatString)));
                        if (dataFormatString == null && cell.CellStyle.DataFormat == 57)
                        {
                            result = cell.DateCellValue.ToString("yyyy\"年\"M\"月\"");
                        }
                        break;
                    }
                case CellType.Formula:
                    result = cell.StringCellValue;
                    break;
                case CellType.Blank:
                    result = GetCellText(cell, cell.CachedFormulaResultType, cellm);
                    break;
                case CellType.Boolean:
                    result = "";
                    break;
                case CellType.Error:
                    result = (cell.BooleanCellValue.ToString() ?? "");
                    break;
                default:
                    result = (cell.ErrorCellValue.ToString() ?? "");
                    break;
            }
            return result;
        }
    }
}
